import SysMenuModel from "../../dao/model/system/SysMenuModel";
import SysRoleModel from "../../dao/model/system/SysRoleModel";
import { IMenuModel } from "../../entities/system/SysMenuEntity";
import SysRoleEntity, { IRoleModel } from "../../entities/system/SysRoleEntity";
import { IPageResponse } from "../../types/CommonType";
import { ValidationError } from "../../utils/errors";

export class SysUserService {
  /**
   * 添加数据
   */
  public static async add(data: SysRoleEntity): Promise<true> {
    // 1. 转换类型
    data = SysRoleEntity.transform(data);
    // 2. 数据验证
    const errors = await data.validateThis();
    if (errors.length > 0) {
      throw new ValidationError(errors[0]);
    }

    const newData = await SysRoleModel.create<IRoleModel>(data);

    const menus: IMenuModel[] = [];
    if (data.menuIds) {
      for (const menuId of data.menuIds) {
        const data = await SysMenuModel.findByPk<IMenuModel>(menuId);
        if (data) {
          menus.push(data);
        }
      }
    }
    for (const item of menus) {
      newData.addMenu(item);
    }

    return true;
  }

  /**
   * 分页获取数据
   */
  public static async findByPage(current: number, size: number, where?: any): Promise<IPageResponse> {
    let data = await SysRoleModel.findAndCountAll<IRoleModel>({
      offset: size * (current - 1),
      limit: size,
      where,
    });

    const result: IPageResponse = {
      total: data.count,
      list: data.rows.map((item) => item.dataValues),
    };

    return result;
  }

  public static async findByList(where?: any) {
    return SysRoleModel.findAll<IRoleModel>({
      where,
    });
  }

  /**
   * 通过id获取数据
   */
  public static async findById(id: string) {
    const data = await SysRoleModel.findByPk<IRoleModel>(id);

    if (data) {
      const menus = await data.getMenu();
      data.dataValues.menuIds = menus.map((item) => item.dataValues.id!);
    }
    return data;
  }

  /**
   * 修改数据
   */
  public static async update(data: any) {
    const result = await SysRoleModel.update<IRoleModel>(data, {
      where: {
        id: data.id,
      },
    });

    const roleData = await SysRoleModel.findByPk<IRoleModel>(data.id);
    if (roleData) {
      await roleData.setMenu(data.menuIds);
    }
    return result;
  }

  /**
   * 删除数据
   */
  public static async delete(id: string) {
    return SysRoleModel.destroy({
      where: {
        id,
      },
    });
  }
}
